//! \file Behavior_TODO.cpp
//! \brief Implements the <code>fullsail_ai::fundamentals::Behavior</code> abstract class.
//! \author Jeremiah Blanchard with code from Cromwell D. Enage

#include <queue>
#include <stack>
#include "Behavior.h"
#include "../Structures/QueueList.h"

namespace fullsail_ai { namespace fundamentals {

	unsigned Behavior::createdCount = 0;
	unsigned Behavior::destroyedCount = 0;

	unsigned Behavior::getCreatedCount()
	{
		return createdCount;
	}

	unsigned Behavior::getDestroyedCount()
	{
		return destroyedCount;
	}

	Behavior::Behavior(char const* _description)
	{
		description = _description;
	}

	char const* Behavior::toString() const
	{
		return description;
	}

	bool Behavior::isLeaf() const
	{
		return false;
	}

	//! \todo
	//!   - Implement the <code>Behavior</code> methods.
	Behavior * Behavior::getChild(size_t index)
	{
		return children[index];
	}
	
	Behavior const * Behavior::getChild(size_t index) const
	{
		return children[index];
	}

	size_t Behavior::getChildCount() const
	{
		return children.size();
	}

	void Behavior::addChild(Behavior* child)
	{
		child->parent = this;
		children.push_back(child);
	}

	void Behavior::breadthFirstTraverse(void (*dataFunction)(Behavior const *)) const
	{
		QueueList<const Behavior*> Nodes;
		Nodes.enqueue(this);
		while (!Nodes.isEmpty())
		{	
			const Behavior *tempNode = Nodes.getFront();
			Nodes.remove(tempNode);
			dataFunction(tempNode);
			unsigned int numChildren = tempNode->getChildCount();
			for (unsigned int i = 0; i < numChildren; i++)
			{
				Nodes.enqueue(tempNode->getChild(i));
			}
		}
	}

	void Behavior::preOrderTraverse(void (*dataFunction)(Behavior const *)) const
	{
		dataFunction(this);
		unsigned int numChildren = getChildCount();
		for (unsigned int i = 0; i < numChildren; i++)
		{
			TraverseHelper(getChild(i), dataFunction, true);
		}
	}

	void Behavior::postOrderTraverse(void (*dataFunction)(Behavior const *)) const
	{
		unsigned int numChildren = getChildCount();
		for (unsigned int i = 0; i < numChildren; i++)
		{
			TraverseHelper(getChild(i), dataFunction, false);
		}
		dataFunction(this);
	}

	void Behavior::TraverseHelper(const Behavior *node, void (*dataFunction)(Behavior const*), bool order) const
	{
		unsigned int numChildren = node->getChildCount();
		if (order == true)
			dataFunction(node);
		for (unsigned int i = 0; i < numChildren; i++)
		{
			TraverseHelper(node->getChild(i), dataFunction, order);
		}
		if (order == false)
			dataFunction(node);
	}

}}  // namespace fullsail_ai::fundamentals
